//
//  Grid.m
//  Game of Life
//
//  Created by James Durkee on 5/12/09.
//  Copyright 2009 __MyCompanyName__. All rights reserved.
//

#import "Grid.h"


@implementation Grid
- (id)initWithRows:(int)r Cols:(int)c {
	self = [super init];
	if (self != nil) {
		generation = 0;
		numberOfRows = r;
		numberOfColumns = c;
		
		grid = [[NSMutableArray alloc] initWithCapacity:numberOfColumns];
		
		for (int c = 0; c < numberOfColumns; c++) {
			NSMutableArray *row = [NSMutableArray arrayWithCapacity:numberOfRows];
			for (int r = 0; r < numberOfRows; r++) {
				[row addObject:[Cell cellWithRow:r Col:c]];
			}
			[grid addObject:row];
		}
	}
	return self;
}

- (id)init {
	self = [super init];
	if (self != nil) {
		generation = 0;
		numberOfRows = 100;
		numberOfColumns = 100;
		
		grid = [[NSMutableArray alloc] initWithCapacity:numberOfColumns];
		
		for (int c = 0; c < numberOfColumns; c++) {
			NSMutableArray *row = [NSMutableArray arrayWithCapacity:numberOfColumns];
			for (int r = 0; r < numberOfRows; r++) {
				[row addObject:[Cell cellWithRow:r Col:c]];
			}
			[grid addObject:row];
		}
	}
	return self;
}

- (void)clear {
	NSEnumerator *c = [grid objectEnumerator];
	id o;
	
	while(o = [c nextObject]){
		NSEnumerator *r = [o objectEnumerator];
		id cell;
		
		while(cell = [r nextObject]){ 
			[cell setAlive:NO];
			[cell setNextState:NO];
		}
	}
	generation = 0;
}

- (Cell *)cellAtRow:(int)r Col:(int)c {
	return [[grid objectAtIndex:c] objectAtIndex:r];
}

- (NSEnumerator *)columnEnumerator {
	return [grid objectEnumerator];
}

- (int)generation {
	return generation;
}

- (int)rows {
	return numberOfRows;
}
- (int)columns {
	return numberOfColumns;
}

-(int)countCellNeighborsAtRow:(int)r Col:(int)c {
	//NSLog(@"Counting: Row: %d Col: %d", r, c);
	int ncount = 0;
	
	if((r > 0) && (r < [self rows] - 1) && (c > 0) && (c < [self columns] - 1)){
		
		if([[self cellAtRow: (r-1) Col: (c-1)] isAlive])
			ncount++;
		if([[self cellAtRow: (r-1) Col: c] isAlive])
			ncount++;
		if([[self cellAtRow: (r-1) Col: (c+1)] isAlive])
			ncount++;
		if([[self cellAtRow: r Col: (c-1)] isAlive])
			ncount++;
		if([[self cellAtRow: r Col: (c+1)] isAlive])
			ncount++;
		if([[self cellAtRow: (r+1) Col: (c-1)] isAlive])
			ncount++;
		if([[self cellAtRow: (r+1) Col: c] isAlive])
			ncount++;
		if([[self cellAtRow: (r+1) Col: (c+1)] isAlive])
			ncount++;
	}
	
	
	return ncount;
	
}

-(void)nextGeneration {
	generation++;
	
	NSEnumerator *c = [grid objectEnumerator];
	id o;
	
	while(o = [c nextObject]){
		NSEnumerator *r = [o objectEnumerator];
		id cell;
		
		while(cell = [r nextObject]){
			[cell setNcount: [self countCellNeighborsAtRow: [cell row] Col: [cell col]]];
			[cell determineNextState];
		}
	}
	
	c = [grid objectEnumerator];
	
	while(o = [c nextObject]){
		NSEnumerator *r = [o objectEnumerator];
		id cell;
		
		while(cell = [r nextObject]){
			[cell setAliveToNextState];
		}
	}
	
	//Insert code to iterate through the grid to find the neighbor count for each cell and then 
	//determine each cells nextState.
	//For each cell do: [Grid countCellNeighborsAtRow:Col] and [Cell determineNextState].
	//eg. [[self cellAtRow: r Col: c] ncount] = [Grid countCellNeighborsAtRow: r Col: c];
	//    [[self cellAtRow: r Col: c] determineNextState];
	
	//Insert code to iterate through the grid to set isAlive to nextState for each cell.
	// eg. [Cell setAliveToNextState];
	
}

@end